package org.pupil.rpc.protocol.serialization.serializationImpl;

import com.caucho.hessian.io.HessianSerializerInput;
import com.caucho.hessian.io.HessianSerializerOutput;
import org.pupil.rpc.protocol.serialization.RpcSerialization;
import org.pupil.rpc.protocol.serialization.SerializationException;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

/**
 * Hessian 序列化
 */
public class HessianSerialization implements RpcSerialization {

    @Override
    public <T> byte[] serialize(T object){
        if (object == null){
            throw new NullPointerException();
        }

        byte[] results;

        // 用于将java对象序列化为Hessian格式的输出流
        HessianSerializerOutput hessianOutput;
        try(ByteArrayOutputStream os = new ByteArrayOutputStream()){ // 创建一个输入流在try结束时关闭
            hessianOutput = new HessianSerializerOutput(os); // 绑定输入流
            hessianOutput.writeObject(object); // 传入对象进行序列化
            hessianOutput.flush(); // 刷新Hessian输出流，确保所有数据都被写入
            results = os.toByteArray(); // 将输入流中的数据转换为字节数组，并将其赋值给results变量
        }catch (Exception e){
            throw new SerializationException(e);
        }

        return results;
    }

    @SuppressWarnings("unchecked") //告诉编译器忽略与类型转换相关的未检查警告
    @Override
    public <T> T deSerialize(byte[] bytes, Class<T> clazz){
        if (bytes == null){
            throw new NullPointerException();
        }

        T result;
        // 用于将Hessian格式的输出流反序列化为java对象
        HessianSerializerInput hessianInput;
        try(ByteArrayInputStream is = new ByteArrayInputStream(bytes)) {
            hessianInput = new HessianSerializerInput(is); // 绑定输入流
            // 将字节数组反序列化为指定的对象类型clazz
            result = (T) hessianInput.readObject(clazz);
        } catch (Exception e) {
            throw new SerializationException(e);
        }

        return result;
    }
}
